/*
 * TextMonitoring.cpp
 *
 *  Created on: 13.11.2011
 *      Author: centimo
 */

#include "TextMonitoring.h"

TextMonitoring::TextMonitoring(QTextEdit* editFieldPointer)
{
    cursorsVector = new QVector<CursorPosition*>();
    changes = new QVector<Change*>();
    editField = editFieldPointer;
    allText = new QString("");

}


void TextMonitoring::sendEvent(eventsType eventType, int selectionStart, int selectionEnd)
{
    if((eventType == CURSOR_POSITION_CHANGED) || (eventType == SELECTION_CHANGED) || (eventType == DROP))
    {
        CursorPosition* temp = new CursorPosition;
        temp->type = eventType;
        temp->begin = selectionStart;
        temp->end = selectionEnd;
        this->cursorsVector->push_back(temp);

    }

    else if(eventType == TEXT_CHANGED)
    {
        CursorPosition* temp = new CursorPosition;
        temp->type = eventType;
        temp->begin = selectionStart;
        temp->end = selectionEnd;
        this->cursorsVector->push_back(temp);


        short i = this->cursorsVector->size()-2;

        if(i == 0)
        {
            Change* changeTemp = new Change;
            changeTemp->type = INSERT;
            changeTemp->beginInSrc = 0;
            changeTemp->endInSrc = temp->begin;
            changeTemp->value = this->editField->toPlainText().mid(0, temp->begin);
            this->changes->push_back(changeTemp);
            makeChange(allText, changeTemp);

        }

        while(i > 0)
        {
            if(this->cursorsVector->at(i)->type == SELECTION_CHANGED)
            {
                if(this->cursorsVector->at(i)->begin < temp->begin)
                {
                    Change* changeTemp = new Change;
                    changeTemp->type = DELETE;
                    changeTemp->beginInSrc = this->cursorsVector->at(i)->begin;
                    changeTemp->endInSrc = this->cursorsVector->at(i)->end;
                    changeTemp->value = this->allText->mid(changeTemp->beginInSrc, changeTemp->endInSrc - changeTemp->beginInSrc);
                    this->changes->push_back(changeTemp);
                    makeChange(allText, changeTemp);
                    //delete changeTemp;

                    changeTemp = new Change;
                    changeTemp->type = INSERT;
                    changeTemp->beginInSrc = this->cursorsVector->at(i)->begin;
                    changeTemp->endInSrc = temp->begin;
                    changeTemp->value = this->editField->toPlainText().mid(this->cursorsVector->at(i)->begin,
                                                                           temp->begin - this->cursorsVector->at(i)->begin);
                    this->changes->push_back(changeTemp);
                    makeChange(allText, changeTemp);
                    //delete changeTemp;

                    break;
                }
                else if((this->cursorsVector->at(i)->end > temp->end) && (this->cursorsVector->at(i)->begin == temp->begin))
                {
                    Change* changeTemp = new Change;
                    changeTemp->type = DELETE;
                    changeTemp->beginInSrc = temp->begin;
                    changeTemp->endInSrc = this->cursorsVector->at(i)->end;
                    changeTemp->value = this->allText->mid(changeTemp->beginInSrc, changeTemp->endInSrc - changeTemp->beginInSrc);
                    this->changes->push_back(changeTemp);
                    makeChange(allText, changeTemp);
                    //delete changeTemp;

                    break;
                }
            }

            else if((this->cursorsVector->at(i)->type == CURSOR_POSITION_CHANGED) || (this->cursorsVector->at(i)->type == TEXT_CHANGED))
            {
                if(this->cursorsVector->at(i)->begin < temp->begin)
                {
                    Change* changeTemp = new Change;
                    changeTemp->type = INSERT;
                    changeTemp->beginInSrc = this->cursorsVector->at(i)->begin;
                    changeTemp->endInSrc = temp->begin;
                    changeTemp->value = this->editField->toPlainText().mid(this->cursorsVector->at(i)->begin,
                                                                           temp->begin - this->cursorsVector->at(i)->begin);
                    this->changes->push_back(changeTemp);
                    makeChange(allText, changeTemp);
                    //delete changeTemp;

                    break;
                }
                else if(this->cursorsVector->at(i)->begin > temp->begin)
                {
                    Change* changeTemp = new Change;
                    changeTemp->type = DELETE;
                    changeTemp->beginInSrc = temp->begin;
                    changeTemp->endInSrc = this->cursorsVector->at(i)->begin;
                    changeTemp->value = this->allText->mid(changeTemp->beginInSrc, changeTemp->endInSrc - changeTemp->beginInSrc);
                    this->changes->push_back(changeTemp);
                    makeChange(allText, changeTemp);
                    //delete changeTemp;

                    break;
                }
            }

            else if(this->cursorsVector->at(i)->type == DROP)
            {
                if(this->cursorsVector->at(i)->end == this->cursorsVector->at(i)->begin)
                {
                    Change* changeTemp = new Change;
                    changeTemp->type = INSERT;
                    changeTemp->beginInSrc = this->cursorsVector->at(i)->begin;
                    changeTemp->endInSrc = temp->end;
                    changeTemp->value = this->editField->toPlainText().mid(this->cursorsVector->at(i)->begin,
                                                                           temp->end - this->cursorsVector->at(i)->begin);
                    this->changes->push_back(changeTemp);
                    makeChange(allText, changeTemp);
                    //delete changeTemp;

                    break;
                }
                else
                {
                    Change* changeTemp = new Change;
                    changeTemp->type = DELETE;
                    changeTemp->beginInSrc = this->cursorsVector->at(i)->begin;
                    changeTemp->endInSrc = this->cursorsVector->at(i)->end;
                    changeTemp->value = this->allText->mid(changeTemp->beginInSrc, changeTemp->endInSrc - changeTemp->beginInSrc);
                    this->changes->push_back(changeTemp);
                    makeChange(allText, changeTemp);
                    //delete changeTemp;

                    changeTemp = new Change;
                    changeTemp->type = INSERT;
                    changeTemp->beginInSrc = temp->end - (this->cursorsVector->at(i)->end - this->cursorsVector->at(i)->begin);
                    changeTemp->endInSrc = temp->end;
                    changeTemp->value = this->editField->toPlainText().mid(temp->end - (this->cursorsVector->at(i)->end - this->cursorsVector->at(i)->begin),
                                                                           this->cursorsVector->at(i)->end - this->cursorsVector->at(i)->begin);
                    this->changes->push_back(changeTemp);
                    makeChange(allText, changeTemp);
                    //delete changeTemp;

                    break;
                }
            }

            i--;
        }


        while(changes->size() > sizeOfChangesQueue)
        {
            delete changes->at(0);
            changes->pop_front();
        }

    }

    while(cursorsVector->size() > sizeOfCursorsQueue)
    {
        delete cursorsVector->at(0);
        cursorsVector->pop_front();
    }
}

QVector<Change*>* TextMonitoring::getChangesVector()
{
    return this->changes;
}


/*
void TextMonitoring::cursorPosCh(QTextCursor* cursor, QTextEdit* outField)
{
    QVector<int> blya(3);
    for(int i=0; i<10; i++)
    {
        blya[i] = 1;
    }
    int a = cursor->position();
    QString bb = "adfafaf";
    outField->setText(bb);
    outField->redo();

   // this->cursorsQueue->enqueue()

}
*/

